#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan  3 10:07:18 2022

@author: sarupa
"""

#import library
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import  Sequential
from tensorflow.keras.layers import Dense
from sklearn.preprocessing import MinMaxScaler
import numpy as np
from matplotlib import pyplot as plt
from numpy import random
from random import seed
import copy


#Load the data set

dataset_in = np.loadtxt('Final_data_set.csv', delimiter=',')


# Define RMSE
def rmse(predictions, targets):

    differences = (predictions - targets)/targets                      

    differences_squared = differences ** 2                    

    mean_of_differences_squared = differences_squared.mean()  

    rmse_val = np.sqrt(mean_of_differences_squared)*100        

    return rmse_val 

# Prepare the data

dataset=np.zeros((len(dataset_in),11))
dataset[:,0]=dataset_in[:,7]
dataset[:,1]=dataset_in[:,2]
dataset[:,2]=dataset_in[:,5]
dataset[:,3]=dataset_in[:,8]
dataset[:,4:11]=dataset_in[:,9:16]

# The min-max scaling approach
sc= MinMaxScaler(feature_range=(0,1))
dataset_scaled = sc.fit_transform(dataset)

# Scale the test data using the scaling parameters of the original data
# dataset_scaled = (dataset - data_min)/(data_max - data_min)

# #Extract the scaling parameters
data_min = sc.data_min_
data_max = sc.data_max_


# Split the original data into training, validation, and testing data sets
data_train = dataset_scaled[:200000,:]
x_train=data_train[:, 1:11]
y_train=data_train[:, 0]
data_validation  = dataset_scaled[400000:475000,:]
x_val=data_validation[:, 1:11]
y_val=data_validation[:, 0]
data_test = dataset_scaled[475000:480000,:]
x_test=data_test[:, 1:11]
y_test=data_test[:, 0]


model=Sequential()
model.add(Dense(120, input_dim=10, activation='relu'))
model.add(Dense(120, activation='relu'))
#model.add(Dense(80, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

#compile the keras model

model.compile(loss='binary_crossentropy',optimizer='adam', metrics=['accuracy'])#,  weighted_metrics= 'sample_weight',)

#fit the keras model
model.fit(x_train,y_train, epochs=25, batch_size=100)

_, accuracy = model.evaluate(x_val,y_val)
print("Acuracy", accuracy*100)

#simulated data
predicted_trajectory=model.predict(x_test)
number_of_states= 1
y_test_unscaled = y_test*(data_max[0:number_of_states]-data_min[0:number_of_states]) + data_min[0:number_of_states]
predicted_trajectory_unscaled = predicted_trajectory*(data_max[0:number_of_states]-data_min[0:number_of_states]) + data_min[0:number_of_states]

plt.figure()
plt.plot(predicted_trajectory_unscaled, 'b')
plt.plot(y_test_unscaled, 'm')
np.shape(x_test)

RMSE=rmse(predicted_trajectory_unscaled[0:400],y_test_unscaled[0:400])
print(RMSE)


#data with noise
x_test1=copy.deepcopy(x_test)
np.random.seed(100) 
sigma_v_m=0.005
Nsim = y_test.shape[0]
v = sigma_v_m*random.randn(Nsim,3)
x_test1[:,0:3]= x_test[:,0:3]+v

predicted_trajectory1=model.predict(x_test1)

predicted_trajectory_unscaled1 = predicted_trajectory1*(data_max[0:number_of_states]-data_min[0:number_of_states]) + data_min[0:number_of_states]


plt.figure()
plt.plot(y_test_unscaled[0:400], 'm:')
plt.plot(predicted_trajectory_unscaled[0:400], 'b--')
plt.plot(predicted_trajectory_unscaled1[0:400], 'g:')
plt.legend(['Data','DNN_testing', 'DNN_testing_noise'])
plt.xlabel("Time step")
plt.ylabel("X_B_3")
np.shape(x_test)

# The RMSE is average of different seed and different testing sets
RMSE=rmse(predicted_trajectory_unscaled1[0:400],y_test_unscaled[0:400])
print(RMSE)

np.savetxt('predicted_trajectory_unscaled1_DNN.txt',predicted_trajectory_unscaled1)
np.savetxt('predicted_trajectory_unscaled_DNN.txt',predicted_trajectory_unscaled)